簡単なメッセージの構成例 - Noise Protocol Framework (2)
Noiseプロトコルの構成要素
Noiseプロトコルでは2種類のメッセージ(ハンドシェイクメッセージとトランスポートメッセージ)を扱います。
最初のハンドシェイクフェーズではハンドシェイクメッセージを使って2者間で公開鍵を交換します。
鍵交換(鍵合意)はDH関数と呼ばれる関数を使い、関数の実行結果をハッシュしたものを共通鍵として使用します。
DH鍵交換には通常、自分の秘密鍵と相手の公開鍵が必要です。Noiseプロトコルでは公開鍵として、一時的な鍵(ephemeral key)と静的な鍵(static key)の2種類の鍵を使用します。
鍵交換のメッセージをやりとりする手順にはパターンがあり、あらかじめ2者間で決められたパターン通りにメッセージをやりとりしてハンドシェイクを行います。
また、ハンドシェイクを実行している間は、両者はステート(状態)と呼ばれる一連の変数を保持しています。ステートにはCipherState、SymmetricState、HandshakeStateの3種類が存在します。
ハンドシェイク確立後はトランスポートメッセージを使って暗号化したデータを送受信することができるようになります。
鍵とメッセージのパターンに関する記法
ハンドシェイクメッセージのパターンを記述するのには、以下のような記号を使用します。
イニシエーター
通信を行う2者のうち、最初にハンドシェイクメッセージを送信する方です。
レスポンダー
通信を行う2者のうち、最初のメッセージをイニシエーターから受信する方です。
"->"
イニシエーターがレスポンダーにメッセージを送ることを意味します。
"<-"
上の逆です。レスポンダーがイニシエーターにメッセージを送ることを意味します。
"e"
一時的なキーを生成して相手に送ることを意味します。
"s"
静的なキーを相手に送ることを意味します。
"ee", "es", "se", "ss"
DH鍵交換が行われたことを意味します。それぞれで交換する鍵の種類がことなります。
"ee"
イニシエーターの一時鍵とレスポンダーの一時鍵
"es"
イニシエーターの一時鍵とレスポンダーの静的鍵
"se"
イニシエーターの静的鍵とレスポンダーの一時鍵
"ss"
イニシエーターの静的鍵とレスポンダーの静的鍵
メッセージの例
上記の記法を使って、ハンドシェイクメッセージを構成してみます。
-> e
<- e, ee
これは一番シンプルなハンドシェイクと言えます。
イニシエーターは一時鍵"e"を生成して、レスポンダーに送信。
レスポンダーも一時鍵"e"を生成して、イニシエーターに送信。
双方の一時鍵を交換したことにより、鍵交換 "ee"が行われ、以後の通信が共通鍵によって行うことができるようになる。
(これは一番シンプルな例としてあげていますが、一時鍵のみの鍵交換で暗号化された通信を行う場合は
悪意の第三者によって、一時鍵が改竄されるリスクを回避できないため、用途は限定されると思います)
各メッセージでは、鍵の情報の後に任意のペイロードを付加することもできます。
鍵交換が行われたあとはペイロードも暗号化されたものが送られます。
別のパターンも見てみます。
-> e
<- e, ee, s, es
これは一時鍵の交換("ee")をしたあと、レスポンダーの(暗号化された)静的公開鍵をイニシエーターに渡して2つ目の鍵交換("es")を行なっています。
これにより、レスポンダーの認証を行うことができます。レスポンダーが2番目のメッセージで提示した静的公開鍵の所有者でなければ、これ以降の暗号化されたトランスポートメッセージを復号して読むことは不可能です。
同様にイニシエーターの認証を行うには、イニシエーターが自身の(暗号化された)静的公開鍵をレスポンダーに送ればよいことになります(下記)。
-> e
<- e, ee, s, es
-> s, se